home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 8: LINUX Games
/
Linux Cubed Series 8 - LINUX Games.iso
/
games
/
muds
/
pennmush.000
/
pennmush-1.50-p8-linux.tar
/
pennmush
/
move.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-04-01
|
15KB
|
609 lines
/* move.c */
#include "copyright.h"
#include <ctype.h>
#include "config.h"
#include "db.h"
#include "interface.h"
#include "match.h"
#include "externs.h"
#include "globals.h"
void enter_room();
void moveto(what, where)
dbref what;
dbref where;
{
enter_room(what, where);
}
void moveit(what, where)
dbref what;
dbref where;
{
dbref loc, old;
/* remove what from old loc */
if ((loc = old = Location(what)) != NOTHING) {
Contents(loc) = remove_first(Contents(loc), what);
}
/* test for special cases */
switch (where) {
case NOTHING:
Location(what) = NOTHING;
return; /* NOTHING doesn't have contents */
case HOME:
where = Exits(what); /* home */
safe_tel(what, where);
return;
/*NOTREACHED*/
break;
}
/* now put what in where */
PUSH(what, Contents(where));
Location(what) = where;
if ((where != NOTHING) && !Dark(where) && (old != where)) {
if (Hearer(what)) {
did_it(what, old, "LEAVE", NULL, "OLEAVE", "has left.",
"ALEAVE", old);
if(Typeof(where) != TYPE_ROOM)
did_it(what, where, NULL, NULL, "OXENTER", NULL, NULL, old);
if(Typeof(old) != TYPE_ROOM)
did_it(what, old, NULL, NULL, "OXLEAVE", NULL, NULL, where);
did_it(what, where, "ENTER", NULL, "OENTER", "has arrived.",
"AENTER", where);
} else {
/* non-listeners only trigger the actions not the messages */
did_it(what, old, NULL, NULL, NULL, NULL, "ALEAVE", old);
did_it(what, where, NULL, NULL, NULL, NULL, "AENTER", where);
}
}
did_it(what, what, "MOVE", NULL, "OMOVE", NULL, "AMOVE", where);
}
#define Dropper(thing) (Hearer(thing) && Connected(Owner(thing)))
void send_contents(loc, dest)
dbref loc;
dbref dest;
{
dbref first;
dbref rest;
first = Contents(loc);
Contents(loc) = NOTHING;
/* blast locations of everything in list */
DOLIST(rest, first) {
Location(rest) = NOTHING;
}
while (first != NOTHING) {
rest = Next(first);
if (Dropper(first)) {
Location(first) = loc;
PUSH(first, Contents(loc));
} else
enter_room(first, Sticky(first) ? HOME : dest);
first = rest;
}
Contents(loc) = reverse(Contents(loc));
}
void maybe_dropto(loc, dropto)
dbref loc;
dbref dropto;
{
dbref thing;
if (loc == dropto)
return; /* bizarre special case */
if (Typeof(loc) != TYPE_ROOM)
return;
/* check for players */
DOLIST(thing, Contents(loc)) {
if (Dropper(thing))
return;
}
/* no players, send everything to the dropto */
send_contents(loc, dropto);
}
void enter_room(player, loc)
dbref player;
dbref loc;
{
dbref old;
dbref dropto;
static int deep = 0;
if (deep++ > 15) {
deep--;
return;
}
if(player < 0 || player >= db_top) {
deep--;
return;
}
#ifdef notdef
if (loc == NOTHING) { /* death to -1 */
free_object(player);
deep--;
return;
}
#endif
/* check for room == HOME */
if (loc == HOME)
loc = Home(player);
if ((Typeof(player) != TYPE_PLAYER) && (Typeof(player) != TYPE_THING)) {
fprintf(stderr, "ERROR: Non object moved!! %d\n", player);
fflush(stderr);
deep--;
return;
}
if (Typeof(loc) == TYPE_EXIT) {
fprintf(stderr, "ERROR: Attempt to move %d to exit %d\n", player, loc);
deep--;
return;
}
/* get old location */
old = Location(player);
/* go there */
moveit(player, loc);
/* if old location has STICKY dropto, send stuff through it */
if ((loc != old) && Dropper(player) &&
(old != NOTHING) && (Typeof(old) == TYPE_ROOM) &&
((dropto = Location(old)) != NOTHING) && Sticky(old))
maybe_dropto(old, dropto);
/* autolook */
look_room(player, loc, 2);
deep--;
}
/* teleports player to location while removing items they shouldnt take */
void safe_tel(player, dest)
dbref player;
dbref dest;
{
dbref first;
dbref rest;
if (dest == HOME)
dest = Home(player);
if (Owner(Location(player)) == Owner(dest)) {
enter_room(player, dest);
return;
}
first = Contents(player);
Contents(player) = NOTHING;
/* blast locations of everything in list */
DOLIST(rest, first) {
db[rest].location = NOTHING;
}
while (first != NOTHING) {
rest = db[first].next;
/* if thing is ok to take then move to player else send home.
* thing is not okay to move if it's STICKY and its home is not
* the player.
*/
if (!controls(player, first) && (Sticky(first) && (Home(first) != player)))
enter_room(first, HOME);
else {
PUSH(first, Contents(player));
db[first].location = player;
}
first = rest;
}
Contents(player) = reverse(Contents(player));
enter_room(player, dest);
}
int can_move(player, direction)
dbref player;
const char *direction;
{
if (!strcasecmp(direction, "home"))
return 1;
/* otherwise match on exits */
init_match(player, direction, TYPE_EXIT);
match_exit();
return (last_match_result() != NOTHING);
}
void do_move(player, direction, type)
dbref player;
const char *direction;
int type; /* type 0 is normal, type 1 is global */
{
dbref exit_m;
dbref loc;
if (!strcasecmp(direction, "home")) {
/* send him home */
/* but steal all his possessions */
if ((loc = Location(player)) != NOTHING && !Dark(player) && !Dark(loc)){
/* tell everybody else */
notify_except(Contents(loc), player,
tprintf("%s goes home.", db[player].name));
}
/* give the player the messages */
notify(player, "There's no place like home...");
notify(player, "There's no place like home...");
notify(player, "There's no place like home...");
safe_tel(player, HOME);
} else {
/* find the exit */
#ifdef DO_GLOBALS
if (type == 1)
init_match_global_check_keys(player, direction, TYPE_EXIT);
else if (type == 2)
init_match_remote_check_keys(getzone(getloc(player)), direction,
TYPE_EXIT);
else
#endif
init_match_check_keys(player, direction, TYPE_EXIT);
match_exit();
switch (exit_m = match_result()) {
case NOTHING:
/* try to force the object */
notify(player, "You can't go that way.");
break;
case AMBIGUOUS:
notify(player, "I don't know which way you mean!");
break;
default:
/* we got one */
/* check to see if we got through */
if (could_doit(player, exit_m)) {
/* special cases for home throughout */
did_it(player, exit_m, "SUCCESS", NULL, "OSUCCESS", NULL, "ASUCCESS",
NOTHING);
if (db[exit_m].location == HOME)
did_it(player, exit_m, "DROP", NULL, "ODROP", NULL, "ADROP",
db[player].exits);
else
did_it(player, exit_m, "DROP", NULL, "ODROP", NULL, "ADROP",
db[exit_m].location);
if (db[exit_m].location == HOME) {
enter_room(player, db[player].exits);
return;
}
switch (Typeof(db[exit_m].location)) {
case TYPE_ROOM:
enter_room(player, db[exit_m].location);
break;
case TYPE_PLAYER:
case TYPE_THING:
{
#ifdef DESTROY
if (db[db[exit_m].location].flags & GOING) {
notify(player, "You can't go that way.");
return;
}
#endif
if (getloc(getloc(exit_m)) == NOTHING)
return;
safe_tel(player, db[exit_m].location);
}
break;
case TYPE_EXIT:
notify(player, "This feature coming soon.");
break;
}
} else
did_it(player, exit_m, "FAILURE", "You can't go that way.",
"OFAILURE", NULL, "AFAILURE", NOTHING);
break;
}
}
}
void do_get(player, what)
dbref player;
const char *what;
{
dbref loc = Location(player);
dbref thing;
char tbuf1[BUFFER_LEN];
if ((Typeof(loc) != TYPE_ROOM) && !(db[loc].flags & ENTER_OK) &&
!controls(player, loc)) {
notify(player, "Permission denied.");
return;
}
init_match_check_keys(player, what, TYPE_THING);
match_neighbor();
if (Long_Fingers(player))
match_absolute(); /* the wizard has long fingers */
else
match_controlled_absolute();
if (match_result() == NOTHING) {
/* take care of possessive get (stealing) */
thing = parse_match_possessive(player, what);
if (!GoodObject(thing)) {
notify(player, "I don't see that here.");
return;
}
/* to steal something, you have to be able to get it, and the
* object must be ENTER_OK and not locked against you.
*/
if (could_doit(player,thing) &&
(Flags(Location(thing)) & ENTER_OK) &&
eval_boolexp(player, db[Location(thing)].enterkey,
Location(thing), 0, ENTERLOCK)) {
notify(Location(thing), tprintf("%s was taken from you.", Name(thing)));
moveto(thing,player);
notify(thing, "Taken.");
sprintf(tbuf1, "takes %s.", db[thing].name);
did_it(player, thing, "SUCCESS", "Taken.", "OSUCCESS", tbuf1, "ASUCCESS",
NOTHING);
} else
did_it(player, thing, "FAILURE", "You can't take that from there.",
"OFAILURE", NULL, "AFAILURE", NOTHING);
return;
} else {
if ((thing = noisy_match_result()) != NOTHING) {
if (db[thing].location == player) {
notify(player, "You already have that!");
return;
}
switch (Typeof(thing)) {
case TYPE_PLAYER:
case TYPE_THING:
if (thing == player) {
notify(player, "You cannot get yourself!");
return;
}
if (could_doit(player, thing)) {
moveto(thing, player);
notify(thing, "Taken.");
sprintf(tbuf1, "takes %s.", db[thing].name);
did_it(player, thing, "SUCCESS", "Taken.", "OSUCCESS", tbuf1,
"ASUCCESS", NOTHING);
} else
did_it(player, thing, "FAILURE", "You can't pick that up.",
"OFAILURE", NULL, "AFAILURE", NOTHING);
break;
case TYPE_EXIT:
notify(player, "You can't pick up exits.");
return;
default:
notify(player, "You can't take that!");
break;
}
}
}
}
void do_drop(player, name)
dbref player;
const char *name;
{
dbref loc;
dbref thing;
#ifdef DESTROY
int reward;
#endif
char tbuf1[BUFFER_LEN];
if ((loc = getloc(player)) == NOTHING)
return;
init_match(player, name, TYPE_THING);
match_possession();
match_controlled_absolute();
switch (thing = match_result()) {
case NOTHING:
notify(player, "You don't have that!");
return;
case AMBIGUOUS:
notify(player, "I don't know which you mean!");
return;
default:
if (db[thing].location != player) {
/* Shouldn't ever happen. */
notify(player, "You can't drop that.");
return;
} else if (Typeof(thing) == TYPE_EXIT) {
notify(player, "Sorry you can't drop exits.");
return;
} else if (IS(loc, TYPE_ROOM, ROOM_TEMPLE)) {
/* sacrifice time */
#ifdef DESTROY
if (Typeof(thing) == TYPE_PLAYER) {
notify(player, "Hey! No blood sacrifices please!.");
return;
}
if (Flags(thing) & SAFE) {
notify(player,
"That object is marked SAFE and cannot be sacrificed.");
return;
}
/* Patched to destroy sacrificed objects */
sprintf(tbuf1, "drops %s.", db[thing].name);
did_it(player, thing, "DROP", "Dropped.", "ODROP", tbuf1,
"ADROP", NOTHING);
notify(player, tprintf("%s is consumed in a burst of flame!",
db[thing].name));
#ifdef FULL_INVIS
if(!Dark(player)) {
notify_except(Contents(loc), player,
tprintf("%s sacrifices %s.", db[player].name,
db[thing].name));
} else {
notify_except(Contents(loc), player,
tprintf("Someone sacrifices %s.", db[thing].name));
}
#else
notify_except(Contents(loc), player,
tprintf("%s sacrifices %s.", db[player].name,
db[thing].name));
#endif
/* check for reward */
if (!controls(player, thing) || (Typeof(player) != TYPE_PLAYER)) {
reward = Pennies(thing);
if (reward < 1 || (Pennies(db[player].owner) > MAX_PENNIES)) {
reward = 1;
} else if (reward > MAX_OBJECT_ENDOWMENT) {
reward = MAX_OBJECT_ENDOWMENT;
}
giveto(db[player].owner, reward);
notify(player, tprintf("You have received %d %s for your sacrifice.",
reward, reward == 1 ? MONEY : MONIES));
}
/* do the actual destruction */
notify(thing, "You have been sacrificed.");
moveto(thing, NOTHING);
Toggles(thing) |= THING_DEST_OK;
do_destroy(player,tprintf("#%d",thing), 1);
return;
#else
notify(player, "Sacrifices are not being accepted. Sorry.");
return;
#endif
} else if (Sticky(thing)) {
notify(thing, "Dropped.");
safe_tel(thing, HOME);
} else if ((Location(loc) != NOTHING) && (Typeof(loc) == TYPE_ROOM) &&
!Sticky(loc)) {
/* location has immediate dropto */
notify(thing, "Dropped.");
moveto(thing, db[loc].location);
} else {
notify(thing, "Dropped.");
moveto(thing, loc);
}
break;
}
sprintf(tbuf1, "drops %s.", db[thing].name);
did_it(player, thing, "DROP", "Dropped.", "ODROP", tbuf1, "ADROP", NOTHING);
}
void do_enter(player, what, is_alias)
dbref player;
const char *what;
int is_alias; /* 1 if we got here via enter alias */
{
dbref thing;
init_match_check_keys(player, what, TYPE_THING);
match_neighbor();
match_exit();
if (is_alias || Hasprivs(player))
match_absolute(); /* necessary for enter aliases to work */
if ((thing = noisy_match_result()) == NOTHING) {
/* notify(player,"I don't see that here."); */
return;
}
switch (Typeof(thing)) {
case TYPE_ROOM:
case TYPE_EXIT:
notify(player, "Permission denied.");
break;
default:
/* the object must pass the lock. Also, the thing being entered */
/* has to be controlled, or must be enter_ok */
if (!(((Flags(thing) & ENTER_OK) || controls(player, thing)) &&
(eval_boolexp(player, db[thing].enterkey, thing, 0, ENTERLOCK)))) {
did_it(player, thing, "EFAIL", "Permission denied.", "OEFAIL",
NULL, "AEFAIL", NOTHING);
return;
}
if(thing == player) {
notify(player, "Sorry, you must remain beside yourself!");
return;
}
safe_tel(player, thing);
break;
}
}
void do_leave(player)
dbref player;
{
if (Typeof(Location(player)) == TYPE_ROOM) {
notify(player, "You can't leave");
return;
}
enter_room(player, db[Location(player)].location);
}
#ifdef DO_GLOBALS
dbref global_exit (player, direction)
dbref player;
const char *direction;
{
init_match_global(player, direction, TYPE_EXIT);
match_exit();
return (last_match_result() != NOTHING);
}
dbref remote_exit (loc, direction)
dbref loc;
const char *direction;
{
init_match_remote(loc, direction, TYPE_EXIT);
match_remote();
return (last_match_result() != NOTHING);
}
#endif
#ifdef DO_GLOBALS
void move_wrapper(player, command)
dbref player;
const char *command;
{
/* check local exit, then zone exit, then global. If nothing is
* matched, treat it as local so player will get an error message.
*/
if (!Mobile(player))
return;
if (can_move(player, command))
do_move(player, command, 0);
else if ((getzone(getloc(player)) != NOTHING) &&
remote_exit(getzone(getloc(player)), command))
do_move(player, command, 2);
else if ((getloc(player) != MASTER_ROOM) &&
global_exit(player, command))
do_move(player, command, 1);
else
do_move(player, command, 0);
}
#else
void move_wrapper(player, command)
dbref player;
const char *command;
{
do_move(player, command, 0);
}
#endif /* DO_GLOBALS */